////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
//  File name:   VoxelAligningTool.cpp
//  Version:     v1.00
//  Created:     25/08/2005 by Sergiy Shaykin.
//  Compilers:   Visual C++ 6.0
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "VoxelAligningTool.h"
#include "ObjectTypeBrowser.h"
#include "PanelTreeBrowser.h"
#include "Viewport.h"

//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CVoxelAligningTool,CEditTool)

//////////////////////////////////////////////////////////////////////////
CVoxelAligningTool::CVoxelAligningTool()
{
	m_bIsDragging = false;
	m_curObj = 0;

	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
		m_curObj = sel->GetObject(0);
}

//////////////////////////////////////////////////////////////////////////
CVoxelAligningTool::~CVoxelAligningTool()
{
}

//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::Display( DisplayContext &dc )
{
}

//////////////////////////////////////////////////////////////////////////
bool CVoxelAligningTool::MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
{
	// Get contrl key status.
	bool bCtrlClick = (flags & MK_CONTROL);
	bool bShiftClick = (flags & MK_SHIFT);

	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (sel->IsEmpty() || m_curObj != sel->GetObject(0))
	{
		GetIEditor()->SetEditTool(0);
		return true;
	}

	if (event == eMouseLDown)
	{
		GetIEditor()->BeginUndo();
		m_bIsDragging = true;
		Vec3 pos = m_curObj->GetPos();
		CPoint pt = GetIEditor()->GetActiveView()->WorldToView(pos);
		m_difPoint = pt-point;
		m_q = m_curObj->GetRotation();

		if ( bCtrlClick && bShiftClick )
			m_bIsDragging = false;
	} 

	if (event == eMouseLDown || event == eMouseMove && m_bIsDragging)
	{
		CPoint pt = point + m_difPoint;
		Vec3 pos = GetIEditor()->GetActiveView()->ViewToWorld(pt, 0, bCtrlClick && !bShiftClick ? false : true );
		Vec3 normal = GetIEditor()->GetActiveView()->ViewToWorldNormal(pt, bCtrlClick && !bShiftClick ? false : true );
		Vec3 zaxis = m_q * Vec3(0,0,1);
		normal.Normalize();
		zaxis.Normalize();
		Quat nq;
		nq.SetRotationV0V1(zaxis, normal);
		m_curObj->SetPos(pos);
		m_curObj->SetRotation(nq * m_q);
	}

	if (event == eMouseLUp)
	{
		if ( !m_bIsDragging && bCtrlClick && bShiftClick )
		{
			Vec3 pos = GetIEditor()->GetActiveView()->ViewToWorld(point, 0, false);
			Vec3 normal = GetIEditor()->GetActiveView()->ViewToWorldNormal(point, false);
			Vec3 zaxis = m_q * Vec3(0,0,1);
			normal.Normalize();
			zaxis.Normalize();
			Quat nq;
			nq.SetRotationV0V1(zaxis, normal);
			m_curObj->SetPos(pos);
			m_curObj->SetRotation(nq * m_q);
		}
		GetIEditor()->AcceptUndo( "Surface Normal Aligning" );
		m_bIsDragging = false;
	}

	return true;
}

//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::BeginEditParams( IEditor *ie,int flags )
{
}

//////////////////////////////////////////////////////////////////////////
void CVoxelAligningTool::EndEditParams()
{
}

//////////////////////////////////////////////////////////////////////////
bool CVoxelAligningTool::OnKeyDown( CViewport *view,uint32 nChar,uint32 nRepCnt,uint32 nFlags )
{ 
	if (nChar == VK_ESCAPE)
	{
		GetIEditor()->SetEditTool(0);
	}
	return false; 
}